import { EnumBetResult, EnumBjlResult } from "@/models/enums/EnumBjlResult";
import { RoundInfo, RecmInfo } from "../ExecutePlan";
import { IMoneyStrategy } from "../IMoneyStrategy";

export interface LdStepOption {
    winStep: number;
    failStep: number;
    baseMoney: number;
    index: number;
    recmMoney: number;
    stepMoney: number;
    stopCount: number;
}

export class LdStepMoneyStrategy implements IMoneyStrategy {
    option: LdStepOption;
    recmV: EnumBjlResult = EnumBjlResult.U;
    recmMoney: number = 0;
    winStep: number = -1;
    failStep: number = 1;
    index: number = 1;
    stepMoney: number = 10;
    stopCount: number = 2;
    runing: boolean = true;
    constructor(name: string, option?: LdStepOption) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                winStep: -1,
                failStep: 1,
                baseMoney: 10,
                index: 1,
                recmMoney: 10,
                stepMoney: 10,
                stopCount: 3
            };
        }
        this.resetStrategy();
    }
    resetStrategy(): void {
        this.recmV = EnumBjlResult.U;
        this.recmMoney = this.option.recmMoney;
        this.winStep = this.option.winStep;
        this.failStep = this.option.failStep;
        this.index = this.option.index;
        this.stepMoney = this.option.stepMoney;
        this.stopCount = this.option.stopCount;
    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = this.recmMoney;

        if (!this.runing) {
            if (userRecm.summaryInfo.prevResult == EnumBetResult.Success && this.stopCount < 0) {
                this.runing = true;
                userRecm.roundSummaryInfo.resetSummaryInfo();
            }
            else if (userRecm.summaryInfo.prevResult == EnumBetResult.Fail && this.stopCount > 0) {
                this.runing = true;
                userRecm.roundSummaryInfo.resetSummaryInfo();
            }
        }

        else if (this.runing) {
            if (userRecm.summaryInfo.prevResult == EnumBetResult.Success) {
                let winStep = 1;
                for (let i = 0; i < winStep; i++) {
                    let stepMoney = (this.index - 1) * this.stepMoney;
                    recmMoney = recmMoney - stepMoney;
                    this.index--;
                    if (this.index < 1) {
                        this.index = 1;
                        recmMoney = this.option.baseMoney;
                    }
                }
                if (this.stopCount > 0 && userRecm.roundSummaryInfo.lwin > this.stopCount) {
                    this.runing = false;
                    userRecm.roundSummaryInfo.resetSummaryInfo();
                }

            }
            else if (userRecm.summaryInfo.prevResult == EnumBetResult.Fail) {
                let failStep = 1;
                for (let i = 0; i < failStep; i++) {
                    let stepMoney = this.index * this.stepMoney;
                    recmMoney = recmMoney + stepMoney;
                    this.index++;
                }
                if (this.stopCount < 0 && userRecm.roundSummaryInfo.lfail >= (-this.stopCount)) {
                    this.runing = false;
                    userRecm.roundSummaryInfo.resetSummaryInfo();
                }
            }
        }


        if (recmMoney < this.option.baseMoney) {
            recmMoney = this.option.baseMoney;
        }
        if (!this.runing) {
            recmV = EnumBjlResult.U;
        }


        this.recmV = recmV;
        this.recmMoney = recmMoney;

        return [recmV, recmMoney];
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.recmMoney];
    }
    strategyName: string;
    debugCompoenent: string = "";
    resetRecm(): void {
        this.recmMoney = 0;
        this.recmV = EnumBjlResult.U;
    }
    copyValue(valueObj: any): void {
        var obj = valueObj as LdStepMoneyStrategy;
        if (obj) {
            this.recmV = obj.recmV;
            this.recmMoney = obj.recmMoney;
            this.index = obj.index;
            this.failStep = obj.failStep;
            this.winStep = obj.winStep;
            this.stepMoney = obj.stepMoney;
            this.runing = obj.runing;
            this.stopCount = obj.stopCount;

        }
    }
}
export interface LdStepV2Option {
    winStepMoney: number;
    failStepMoney: number;
    baseMoney: number;
    reverse: boolean;
    jumpCount: number;
    currentMoney?: number;
}

export class LdStepV2MoneyStrategy implements IMoneyStrategy {
    option: LdStepV2Option;
    recmV: EnumBjlResult = EnumBjlResult.U;
    recmMoney: number = 0;
    currentMoney: number = 0;
    winStepMoney: number = 0;
    failStepMoney: number = 0;
    baseMoney: number = 0;
    jumpCount: number = 20;
    runing: boolean = true;
    reverse: boolean = false;
    level: number = 0;
    constructor(name: string, option?: LdStepV2Option) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                winStepMoney: 10,
                failStepMoney: -10,
                baseMoney: 10,
                reverse: false,
                currentMoney: 10,
                jumpCount: 20
            };
        }
        this.resetStrategy();
    }
    resetStrategy(): void {
        this.recmV = EnumBjlResult.U;
        this.baseMoney = this.option.baseMoney;
        this.recmV = EnumBjlResult.U;
        this.recmMoney = 0;
        this.currentMoney = this.option.currentMoney ?? this.baseMoney;
        this.winStepMoney = this.option.winStepMoney;
        this.failStepMoney = this.option.failStepMoney;
        this.jumpCount = this.option.jumpCount;
        this.runing = true;
        this.reverse = this.option.reverse;
        this.level = 0;
    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = this.currentMoney;
        let wf = recmInfo.summaryInfo.failCount - recmInfo.summaryInfo.winCount;

        if (this.runing) {
            if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
                recmMoney = this.currentMoney + this.winStepMoney
            }
            else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
                recmMoney = recmMoney + this.failStepMoney;
            }

            if (this.level == 0 && wf >= this.jumpCount) {
                recmMoney = 200;
                this.level = 2;
            }
            else if (this.level > 0 && recmMoney <= this.baseMoney) {
                this.level += 2;
                recmMoney = this.baseMoney * (this.level) * 10
            }

        }


        if (recmMoney < this.option.baseMoney) {
            recmMoney = this.option.baseMoney;
        }
        if (!this.runing) {
            recmV = EnumBjlResult.U;
        }

        if (recmMoney < this.baseMoney) recmMoney = this.baseMoney;

        this.currentMoney = recmMoney;
        this.recmV = recmV;
        this.recmMoney = recmMoney;

        return [recmV, recmMoney];
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.recmMoney];
    }
    strategyName: string;
    debugCompoenent: string = "";
    resetRecm(): void {
        this.recmMoney = 0;
        this.recmV = EnumBjlResult.U;
    }
    copyValue(valueObj: any): void {
        var obj = valueObj as LdStepV2MoneyStrategy;
        if (obj) {
            this.recmV = obj.recmV;
            this.recmV = obj.recmMoney;
            this.recmMoney = obj.recmMoney;
            this.currentMoney = obj.currentMoney;
            this.winStepMoney = obj.winStepMoney;
            this.failStepMoney = obj.failStepMoney;
            this.jumpCount = obj.jumpCount;
            this.runing = obj.runing;
            this.reverse = obj.reverse;
            this.level = obj.level;
        }
    }
}
export interface LdStepV3Option {
    winStepMoney: number;
    failStepMoney: number;
    baseMoney: number;
    reverse: boolean;
    jumpCount: number;
    currentMoney?: number;
    winLimit: number;
    failLimit: number;
}

export class LdStepV3MoneyStrategy implements IMoneyStrategy {
    option: LdStepV3Option;
    recmV: EnumBjlResult = EnumBjlResult.U;
    recmMoney: number = 0;
    currentMoney: number = 0;
    winStepMoney: number = 0;
    failStepMoney: number = 0;
    baseMoney: number = 0;
    jumpCount: number = 20;
    runing: boolean = true;
    reverse: boolean = false;
    level: number = 0;
    winLimit: number = 2;
    failLimit: number = 3;
    constructor(name: string, option?: LdStepV3Option) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                winStepMoney: 10,
                failStepMoney: -10,
                baseMoney: 10,
                reverse: false,
                currentMoney: 10,
                jumpCount: 20,
                winLimit: 2,
                failLimit: 3
            };
        }
        this.resetStrategy();
    }
    resetStrategy(): void {
        this.recmV = EnumBjlResult.U;
        this.baseMoney = this.option.baseMoney;
        this.recmV = EnumBjlResult.U;
        this.recmMoney = 0;
        this.currentMoney = this.option.currentMoney ?? this.baseMoney;
        this.winStepMoney = this.option.winStepMoney;
        this.failStepMoney = this.option.failStepMoney;
        this.jumpCount = this.option.jumpCount;
        this.runing = true;
        this.reverse = this.option.reverse;
        this.winLimit = this.option.winLimit;
        this.failLimit =  this.option.failLimit;
        this.level = 0;
    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = this.currentMoney;
        let wf = recmInfo.summaryInfo.failCount - recmInfo.summaryInfo.winCount;
        let roundWf = recmInfo.roundSummaryInfo.winCount - recmInfo.roundSummaryInfo.failCount;
        if (this.runing) {
            if (roundWf > 0
                && (roundWf % this.winLimit) == 0
                && recmInfo.summaryInfo.prevResult == EnumBetResult.Success
            ) {
                recmMoney = this.currentMoney + this.winStepMoney
                recmInfo.roundSummaryInfo.resetSummaryInfo();
            }
            else if (roundWf < 0
                && (roundWf % this.failLimit == 0)
                && recmInfo.summaryInfo.prevResult == EnumBetResult.Fail
            ) {
                recmMoney = recmMoney + this.failStepMoney;
                recmInfo.roundSummaryInfo.resetSummaryInfo();
            }

            // if (this.level == 0 && wf >= this.jumpCount) {
            //     recmMoney = 200;
            //     this.level = 2;
            // }
            // else if (this.level > 0 && recmMoney <= this.baseMoney) {
            //     this.level += 2;
            //     recmMoney = this.baseMoney * (this.level) * 10
            // }

        }


        if (recmMoney < this.option.baseMoney) {
            recmMoney = this.option.baseMoney;
        }
        if (!this.runing) {
            recmV = EnumBjlResult.U;
        }

        if (recmMoney < this.baseMoney) recmMoney = this.baseMoney;

        this.currentMoney = recmMoney;
        this.recmV = recmV;
        this.recmMoney = recmMoney;

        return [recmV, recmMoney];
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.recmMoney];
    }
    strategyName: string;
    debugCompoenent: string = "";
    resetRecm(): void {
        this.recmMoney = 0;
        this.recmV = EnumBjlResult.U;
    }
    copyValue(valueObj: any): void {
        var obj = valueObj as LdStepV3MoneyStrategy;
        if (obj) {
            this.recmV = obj.recmV;
            this.recmV = obj.recmMoney;
            this.recmMoney = obj.recmMoney;
            this.currentMoney = obj.currentMoney;
            this.winStepMoney = obj.winStepMoney;
            this.failStepMoney = obj.failStepMoney;
            this.jumpCount = obj.jumpCount;
            this.runing = obj.runing;
            this.reverse = obj.reverse;
            this.winLimit = obj.winLimit;
            this.failLimit = obj.failLimit;
            this.level = obj.level;
        }
    }
}